﻿import { defineStore } from "pinia";
import apiClient from "../services/api";

export type Article = {
  id: string;
  title: string;
  summary: string;
  body: string;
  coverImage: string;
  category: string;
};

export type Ingredient = {
  name: string;
  amount: string;
};

export type Recipe = {
  id: string;
  name: string;
  calories: number;
  tags: string[];
  image: string;
  ingredients: Ingredient[];
  method: string;
};

export type WellnessGuide = {
  id: string;
  title: string;
  icon: string;
  image: string;
  tips: string[];
};

export type AdminUser = {
  id: string;
  email: string;
  name: string;
  role: "user" | "admin";
};

export type UserProfile = {
  userId: string;
  height: number | null;
  weight: number | null;
  gender: "male" | "female" | "";
  age: number | null;
  bmi: number | null;
  bmr: number | null;
  goal: string;
  updatedAt: string | null;
};

type DashboardPayload = {
  articles: Article[];
  recipes: Recipe[];
  guides: WellnessGuide[];
};

type HealthProfileRow = UserProfile & {
  email: string;
  name: string;
  role: "user" | "admin";
  updatedAt: string | null;
};

const defaultProfile = (): UserProfile => ({
  userId: "",
  height: null,
  weight: null,
  gender: "",
  age: null,
  bmi: null,
  bmr: null,
  goal: "记录你的健康目标",
  updatedAt: null,
});

export const useContentStore = defineStore("content", {
  state: () => ({
    articles: [] as Article[],
    recipes: [] as Recipe[],
    guides: [] as WellnessGuide[],
    users: [] as AdminUser[],
    userProfile: defaultProfile(),
    healthProfiles: [] as HealthProfileRow[],
    isHydrated: false,
    loading: false,
    error: "",
  }),
  getters: {
    articleById: (state) => (id: string) => state.articles.find((article) => article.id === id),
  },
  actions: {
    async fetchDashboard() {
      const { data } = await apiClient.get<DashboardPayload>("/dashboard");
      this.articles = data.articles;
      this.recipes = data.recipes;
      this.guides = data.guides;
      this.isHydrated = true;
      return data;
    },
    async bootstrap() {
      if (!this.isHydrated) {
        try {
          await this.fetchDashboard();
        } catch (error) {
          this.error = "数据加载失败，请稍后重试";
        }
      }
    },
    async fetchUserProfile() {
      try {
        const { data } = await apiClient.get<UserProfile>("/profile");
        this.userProfile = { ...data };
        return data;
      } catch (error) {
        this.userProfile = defaultProfile();
        throw error;
      }
    },
    async updateUserProfile(payload: Partial<UserProfile>) {
      const { data } = await apiClient.patch<UserProfile>("/profile", payload);
      this.userProfile = { ...data };
      return data;
    },
    async createRecipe(payload: Omit<Recipe, "id">) {
      const { data } = await apiClient.post<Recipe>("/recipes", payload);
      this.recipes.push(data);
      return data;
    },
    async updateRecipe(id: string, payload: Partial<Recipe>) {
      const { data } = await apiClient.put<Recipe>(`/recipes/${id}`, payload);
      const index = this.recipes.findIndex((recipe) => recipe.id === id);
      if (index !== -1) {
        this.recipes[index] = data;
      }
      return data;
    },
    async deleteRecipe(id: string) {
      await apiClient.delete(`/recipes/${id}`);
      this.recipes = this.recipes.filter((recipe) => recipe.id !== id);
    },
    async createGuide(payload: Omit<WellnessGuide, "id">) {
      const { data } = await apiClient.post<WellnessGuide>("/guides", payload);
      this.guides.push(data);
      return data;
    },
    async updateGuide(id: string, payload: Partial<WellnessGuide>) {
      const { data } = await apiClient.put<WellnessGuide>(`/guides/${id}`, payload);
      const index = this.guides.findIndex((guide) => guide.id === id);
      if (index !== -1) {
        this.guides[index] = data;
      }
      return data;
    },
    async deleteGuide(id: string) {
      await apiClient.delete(`/guides/${id}`);
      this.guides = this.guides.filter((guide) => guide.id !== id);
    },
    async fetchUsers() {
      const { data } = await apiClient.get<AdminUser[]>("/users");
      this.users = data;
      return data;
    },
    async updateUserRole(id: string, role: "user" | "admin") {
      const { data } = await apiClient.patch<AdminUser>(`/users/${id}`, { role });
      const index = this.users.findIndex((user) => user.id === id);
      if (index !== -1) {
        this.users[index] = data;
      }
      return data;
    },
    async deleteUser(id: string) {
      await apiClient.delete(`/users/${id}`);
      this.users = this.users.filter((user) => user.id !== id);
      this.healthProfiles = this.healthProfiles.filter((profile) => profile.userId !== id);
    },
    async fetchHealthProfiles() {
      const { data } = await apiClient.get<HealthProfileRow[]>("/health-profiles");
      this.healthProfiles = data.map((item) => ({
        ...item,
        userId: item.userId ?? "",
        updatedAt: item.updatedAt ?? null,
      }));
      return this.healthProfiles;
    },
    async updateHealthProfile(userId: string, payload: Partial<UserProfile>) {
      const { data } = await apiClient.put<UserProfile>(`/health-profiles/${userId}`, payload);
      const index = this.healthProfiles.findIndex((item) => item.userId === userId);
      const base: HealthProfileRow =
        this.healthProfiles[index] ??
        ({
          userId,
          email: "",
          name: "",
          role: "user",
          height: null,
          weight: null,
          gender: "",
          age: null,
          bmi: null,
          bmr: null,
          goal: "记录你的健康目标",
          updatedAt: null,
        } as HealthProfileRow);
      const merged: HealthProfileRow = {
        ...base,
        ...data,
        userId: data.userId ?? userId,
        updatedAt: data.updatedAt ?? base.updatedAt ?? null,
      };
      if (index !== -1) {
        this.healthProfiles.splice(index, 1, merged);
      } else {
        this.healthProfiles.push(merged);
      }
      if (this.userProfile.userId === userId || (!this.userProfile.userId && data.userId === userId)) {
        this.userProfile = { ...this.userProfile, ...data, userId: data.userId ?? userId };
      }
      return data;
    },
    reset() {
      this.userProfile = defaultProfile();
      this.healthProfiles = [];
    },
  },
});
